<?php

namespace App\Model\Dao;

use App\Model\Enum\OrderHandleStatusEnum;
use App\Utils\CustomUtils;
use App\Concern\BaseDao;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Arr;
use Redis;
use App\Utils\RedisUtils;
use Hyperf\Utils\Codec\Json;

/**
 * CommissionSalesDao
 */
class CommissionSalesDao extends BaseDao {

    /**
     * 表名常量
     * 联表的时候通过XxxDao::TABLE获取
     */
    const TABLE = "commission_sales";

    // 不支持软删除
    protected $softDelete = null;

    /**
     * 父类中通过静态函数获取表名, 因为不能通过静态常量获取, 这个函数是固定写在子类中的
     */
    public static function table (): string {
        return self::TABLE;
    }

    public function getCount ($param) {
        $builder = $this->_buildQueryString($param);
        return Db::table("tmp")->fromSub($builder, "tmp")->count("tmp.id");
    }

    /**
     * 排序
     *
     * @param Builder $builder
     * @param array   $params
     *
     * @return Builder|mixed
     */
    protected function _buildOrder (Builder $builder, $params = []) {

        // 通过前端提交的参数排序
        if (Arr::exists($params, "orderBy")) {
            [$prop, $order] = $params["orderBy"];
            if (in_array($order, ["asc", "desc"])) {
                //switch ($prop) {
                //    case "yieldMonth":
                //        $builder->orderBy("main.yieldMonth", $order);
                //        break;
                //    default:
                //        break;
                //}
            }
        }

        // 如果友其他固定的排序需求, 在这里写, 例如按照时间降序
        $builder->orderBy("main.createTime", "desc");

        // 追加父类的排序, 父类按照ID升序, 保证排序结果唯一
        return parent::_buildOrder($builder, $params);
    }

    /**
     * 查询条件
     *
     * @param $params
     *
     * @return Builder
     */
    protected function _buildQueryString ($params) {
        // 本表一律命名为main
        $main = sprintf("%s AS main", self::TABLE);
        // 联表表明获取
        $admin = sprintf("%s AS admin", SysAdminDao::TABLE);
        $trans = sprintf("%s AS trans", CommissionSalesTransDao::TABLE);
        $builder = DB::table($main)->leftJoin($admin, "main.salesId", "=", "admin.id")->leftJoin($trans, "main.transId", "=", "trans.id")->selectRaw(join(",", [
            "main.id",
            "main.successCount",
            "main.settleAmount",
            "main.serviceFee",
            "main.commission",
            "main.statMonth",
            "main.mchId",
            "main.mchNo",
            "main.salesId",
            "main.level",
            "main.settleCurrency",
            "main.commissionRate",
            "admin.realName as salesName",
            "ifnull(trans.handleStatus, -1) as transStatus",
        ]))->where("main.delFlag", 0);

        // 通过 Arr::exists 来判断是否存在该键, isset不准确
        (Arr::exists($params, "salesId") && !empty($params["salesId"])) && $builder->where("main.salesId", "=", $params['salesId']);
        Arr::exists($params, "statYear") && $builder->whereRaw("substr(main.statMonth, 1, 4) = '{$params['statYear']}'");
        Arr::exists($params, "statMonth") && $builder->whereBetween("main.statMonth", $params['statMonth']);
        (Arr::exists($params, "mchIdList") && $params["mchIdList"] !== "") && $builder->whereIn("main.mchId", $params['mchIdList']);
        return $builder;
    }

    /**
     * 获取销售可提现金额列表
     *
     * @param $param
     *
     * @return array
     */
    public function getSalesBalanceList ($param) {

        $salesId = $param['salesId'];

        // 计算销售总佣金
        $sales = sprintf('%s AS sales', self::TABLE);

        $builder = Db::table($sales);

        $builder->where('sales.salesId', $salesId);

        $builder->groupBy(['sales.settleCurrency']);

        $builder->selectRaw(join(',', [
            'sales.settleCurrency AS currency',
            'SUM(sales.commission) AS amount',
        ]));

        $salesList = $builder->get()->toArray();
        $salesList = array_column($salesList, 'amount', 'currency');

        // 计算销售总提现(未驳回的)
        $trans = sprintf('%s AS trans', CommissionSalesTransDao::TABLE);

        $builder = Db::table($trans);

        $builder->whereNotIn('trans.handleStatus', [
            OrderHandleStatusEnum::SECOND_REJECT,
            OrderHandleStatusEnum::FIRST_REJECT,
        ]);
        $builder->where('trans.salesId', $salesId);

        $builder->groupBy(['trans.commissionCurrency']);

        $builder->selectRaw(join(',', [
            'trans.commissionCurrency AS currency',
            'SUM(trans.commission) AS amount',
        ]));

        $transList = $builder->get()->toArray();
        $transList = array_column($transList, 'amount', 'currency');

        $currencyList = array_unique(array_merge(array_keys($salesList), array_keys($transList)));

        $balList = [];

        foreach ($currencyList as $currency) {
            if ($currency) {
                array_push($balList, [
                    'currency' => $currency,
                    'amount'   => (int) Arr::get($salesList, $currency, 0) - (int) Arr::get($transList, $currency, 0),
                ]);
            }
        }

        return $balList;
    }


}
